package com.hyt.it.ogt.kq.common.gov.secmodule;

import com.sun.jna.ptr.IntByReference;
import org.apache.commons.lang3.StringUtils;

import com.sun.jna.Memory;
import com.sun.jna.Pointer;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;

/**
 * 加密模块工具类
 *
 * @author liuq
 * @since 2021-06-01
 */
@Slf4j
public class SecModuleUtil {



	/**
	 * 加密字符串，如：考场注册码，身份证号，姓名等
	 * @param text 明文
	 * @return 密文，加密失败返回null
	 */
	public static String encrypString(String szPlaintext) {
		try {
			byte[] arrGbk = szPlaintext.getBytes("GBK");
			int nGbkSize = arrGbk.length + 10;
			byte[] arrPlaintextGbk = Arrays.copyOf(arrGbk, nGbkSize);
			arrPlaintextGbk[arrGbk.length] = 0;
			arrPlaintextGbk[arrGbk.length+1] = 0;
			int nOutBufSize = arrPlaintextGbk.length * 2 + 10;
			Pointer pszGbk_CiphertextBuf = new Memory(nOutBufSize);
			int result = SecModule.INSTANCE.EncrypString(arrPlaintextGbk, pszGbk_CiphertextBuf);
//			byte[] szInText = text.getBytes("GB2312");
//			int outBufSize = szInText.length * 4 + 10;
//			Pointer outBuf = new Memory(outBufSize) ;
//			outBuf.clear(outBufSize);
//			int result = SecModule.INSTANCE.EncrypString(szInText, outBuf);
			//int result = SecModule.INSTANCE.EncrypString_s(szInText, szInText.length, outBuf, outBufSize);
			if (result == 0) {
				return pszGbk_CiphertextBuf.getString(0);
			} else {
				return null;
			}
		} catch (Exception ex){
			return null;
		}
	}


	/**
	 * 加密字符串，如：考场注册码，身份证号，姓名等
	 * @param text 明文
	 * @return 密文，加密失败返回null
	 */
	public static String encrypStringNew(String text) {
		try {
			long size = text.length() * 4 + 10L;
			Pointer point = new Memory(size) ;
			int result = SecModule.INSTANCE.EncrypString(text, point);
			if (result == 0) {
				return point.getString(0);
			} else {
				return null;
			}
		} catch (Exception ex){
			return null;
		}
	}






	/**
	 * 解密字符串 如：考场注册码，
	 * @param text 密文
	 * @return 明文，解密失败返回null
	 */
	public static String decrypString(String text) {
		try {
			long size = text.length() / 2 + 10L;
			Pointer point = new Memory(size) ;
			point.clear(size);
			int result = SecModule.INSTANCE.DecrypString2(text.getBytes("GB2312"), point);
			if (result == 0) {
				return point.getString(0,"ANSI");
			} else {
				return null;
			}
		}catch (Exception ex){
			return null;
		}
	}


	public static String decrypStringNew(String text) {
		try {
			long size = text.length() / 2 + 10L;
			Pointer point = new Memory(size) ;
			int result = SecModule.INSTANCE.DecrypString(text, point);
			if (result == 0) {
				return point.getString(0);
			} else {
				return null;
			}
		}catch (Exception ex){
			return null;
		}
	}




	/**
	 * 加密密码，1-个人补时 10，30分钟 2-整场考试密码 3-个人迟到密码 4-单机考试密码
	 * @param
	 * @return
	 */
	public static String genExamPass(String timeRoomCode,int type,int timeLength) {
		try {
			long size = timeRoomCode.length() / 2 + 10L;
			Pointer point = new Memory(size) ;
			int result = SecModule.INSTANCE.GenExamPass(timeRoomCode.getBytes("GB2312"), type,timeLength,point);
			if (result == 0) {
				return point.getString(0,"ANSI");
			} else {
				return null;
			}
		}catch (Exception ex){
			return null;
		}
	}



	/**
	 * 答案解密方式(cs)--旧
	 * @param key 密码：小题号
	 * @param str 密文：答案加密后的密文
	 * @return
	 */
	public static String encrypString(int key, String str) {
		String answer = null;

		if (StringUtils.isBlank(str)) {
			return "";
		}

		byte[] data = str.getBytes();
		StringBuilder buffer = new StringBuilder();
		int daLength = str.length();
		int ch = daLength / 4;
		if (daLength % 2 == 0) {
			for (int i = 1; i < data.length / 2 + 1; i += 2) {
				if ((data[(i * 2 - 2)] >= 71) && (data[(i * 2 - 2)] <= 86) && (data[(i * 2 - 1)] >= 71) && (data[(i * 2 - 1)] <= 86)) {
					int v1 = data[(i * 2 - 2)] - 71 << 4 | data[(i * 2 - 1)] - 71;
					int v2 = data[((i + 1) * 2 - 2)] - 71 << 4 | data[((i + 1) * 2 - 1)] - 71;
					int v = v1 ^ v2 << 8;
					buffer.append((char) (v ^ ch ^ key));
					ch = v;
				}
			}
		}
		answer = buffer.toString();

		if (StringUtils.isBlank(answer)) {
			return "";
		}
		return answer;
	}

	/**
	 * 答案解密（CS） - 新
	 * @param key 秘钥：准考证号
	 * @param str 密文：答案加密后的密文
	 * @return
	 */
	public static String encrypString(String key, String str) {
		char[] chars = key.toCharArray();
		int len = chars.length;
		for (int i = 0; i < chars.length; ++i) {
			int num = chars[i] * (i + 1);
			len += num;
		}
		return encrypString(len, str);
	}
	//======================================================


	/**
	 * hex（16进制）转 byte[] 字符串
	 * @param hex
	 * @return
	 */
	@SneakyThrows
	private static String hexToByteStr(String hex) {
		return new String(hexToByte(hex));
	}

	/**
	 * hex（16进制）转 byte[]
	 * @param hex
	 * @return
	 */
	@SneakyThrows
	private static byte[] hexToByte(String hex) {

		int len = hex.getBytes().length;
		if (len % 2 != 0) {
			throw new Exception("密文错误");
		}

		byte[] bytes = new byte[len / 2];
		for(int i = 0; i < len; i += 2) {
			String item = new String(hex.getBytes(), i, 2);
			bytes[i / 2] = (byte)Integer.parseInt(item, 16);
		}

		return bytes;
	}


}
